package controller

import (
	"strings"
	"user-go/entity"

	"github.com/androidsr/sc-go/model"
	"github.com/androidsr/sc-go/sbuilder"
	"github.com/androidsr/sc-go/sgin"
	"github.com/androidsr/sc-go/sno"
	"github.com/androidsr/sc-go/sorm"
	"github.com/gin-gonic/gin"
)

func init() {
	sgin.AddRouter(SysRolesController{})
}

type SysRolesController struct {
}

type RolesData struct {
	Id      string   `json:"id"`
	Name    string   `json:"name"`
	MenuIds []string `json:"menuIds"`
}

// 查询
// @Router [get] [/sysroles/:id]
func (SysRolesController) Get(c *gin.Context) any {
	id := c.Param("id")
	data := new(entity.SysRoles)
	data.Id = id
	err := sorm.DB.GetOne(data)
	if err != nil {
		return model.NewFailDefault("获取对象失败")
	}

	roleMenu := make([]entity.SysRoleMenu, 0)
	err = sorm.DB.SelectList(&roleMenu, &entity.SysRoleMenu{RoleId: data.Id})
	if err != nil {
		return model.NewFailDefault("获取对象失败")
	}
	result := RolesData{Id: id, Name: data.Name}
	menuIds := make([]string, 0)
	for _, v := range roleMenu {
		menuIds = append(menuIds, v.MenuId)
	}
	result.MenuIds = menuIds
	return result
}

// 增加
// @Router [post] [/sysroles]
func (SysRolesController) Post(c *gin.Context, in *RolesData) any {
	in.Id = sno.GetString()

	tx := sorm.DB.MustBegin()
	err := sorm.DB.InsertTx(tx, &entity.SysRoles{
		Id:   in.Id,
		Name: in.Name,
	})
	if err != nil {
		tx.Rollback()
		return model.NewFailDefault("增加失败")
	}
	for _, v := range in.MenuIds {
		menu := new(entity.SysMenus)
		menu.Id = v
		err := sorm.DB.SelectOneTx(tx, menu, menu)
		if err != nil || menu == nil {
			tx.Rollback()
			break
		}
		err = sorm.DB.InsertTx(tx, &entity.SysRoleMenu{RoleId: in.Id, MenuId: v, ButtonIds: menu.BtnId})
		if err != nil {
			tx.Rollback()
			break
		}
	}
	tx.Commit()
	return model.NewOK(nil)
}

// 修改
// @Router [put] [/sysroles/edit]
func (SysRolesController) Put(c *gin.Context, in *RolesData) any {
	oldMenuIds := make([]entity.SysRoleMenu, 0)
	err := sorm.DB.SelectList(&oldMenuIds, entity.SysRoleMenu{RoleId: in.Id})
	if err != nil {
		return model.NewFailDefault(err.Error())
	}
	//删除不要需要的权限菜单
	tx := sorm.DB.MustBegin()
	for _, v := range oldMenuIds {
		flag := false
		for _, vv := range in.MenuIds {
			if v.MenuId == vv {
				flag = true
				break
			}
		}
		if !flag {
			err := sorm.DB.DeleteTx(tx, entity.SysRoleMenu{RoleId: v.RoleId, MenuId: v.MenuId})
			if err != nil {
				tx.Rollback()
				return model.NewFailDefault("更新失败")
			}
		}
	}
	//更新权限并新增按钮权限列表（只更新未增加的）
	for _, v := range in.MenuIds {
		b := sorm.DB.GetCount(entity.SysRoleMenu{RoleId: in.Id, MenuId: v})
		if b == 0 {
			menu := new(entity.SysMenus)
			menu.Id = v
			err := sorm.DB.GetOne(menu)
			if err != nil || menu == nil {
				return model.NewFailDefault(err.Error())
			}
			err = sorm.DB.InsertTx(tx, &entity.SysRoleMenu{RoleId: in.Id, MenuId: v, ButtonIds: menu.BtnId})
			if err != nil {
				tx.Rollback()
				return model.NewFailDefault("更新失败")
			}
		}
	}
	err = sorm.DB.UpdateTx(tx, &entity.SysRoles{Id: in.Id, Name: in.Name}, "id")
	if err != nil {
		tx.Rollback()
		return model.NewFailDefault("更新失败")
	}
	tx.Commit()
	return model.NewOK(nil)
}

// 删除
// @Router [delete] [/sysroles/:id]
func (SysRolesController) Delete(c *gin.Context) any {
	id := c.Param("id")
	if id == "" {
		return model.NewFailDefault("主键不能为空")
	}
	tx := sorm.DB.MustBegin()
	err := sorm.DB.DeleteTx(tx, &entity.SysRoleMenu{RoleId: id})
	if err != nil {
		tx.Rollback()
		return model.NewFailDefault("删除失败")
	}
	err = sorm.DB.DeleteTx(tx, &entity.SysRoles{Id: id})
	if err != nil {
		tx.Rollback()
		return model.NewFailDefault("删除失败")
	}
	tx.Commit()
	return model.NewOK(nil)
}

type SysRolesQuery struct {
	Page      model.PageInfo  `json:"page"`
	QueryData entity.SysRoles `json:"queryData"`
}

// 查询列表
// @Router [post] [/sysroles/page]
func (SysRolesController) QueryTables(c *gin.Context, in *SysRolesQuery) any {
	userId := c.GetString(USER)
	ids := strings.Split(c.GetString(ROLE), ",")

	sql := `select * from sys_roles where 1=1 `
	b := sbuilder.Builder(sql)
	if userId != "admin" {
		b.Multiple().Ands(b.And().In("id", ids), b.Or().Eq("crt_opr", userId))
	}
	b.Append("or crt_opr = ''")
	data := make([]entity.SysRoles, 0)
	sql, values := b.Build()
	return sorm.DB.SelectPage(&data, in.Page, sql, values...)
}

// 分页下拉
// @Router [post] [/sysroles/list]
func (SysRolesController) QuerySelect(c *gin.Context, in *model.SelectQueryDTO) any {
	userId := c.GetString(USER)
	ids := strings.Split(c.GetString(ROLE), ",")
	sql := `select a.id as value, name as label from sys_roles a where 1=1 `
	data := make([]model.SelectVO, 0)
	b := sbuilder.Builder(sql)
	if userId != "admin" {
		b.Multiple().Ands(b.And().In("a.id", ids), b.Or().Eq("crt_opr", userId))
	}
	b.Like("CONCAT(id,name)", in.Label)
	b.Multiple().Ors(b.In("id", in.Selected))
	b.Append("or crt_opr = ''")
	sql, values := b.Build()
	return sorm.DB.SelectPage(&data, in.Page, sql, values...)
}
